﻿using DevExpress.Blazor;
using DevExpress.Blazor.Internal;
using DevExpress.ExpressApp.Blazor.Editors.Models;
using Microsoft.AspNetCore.Components;
using System.ComponentModel;
using System.Reflection;

namespace EasyXaf.TreeListEditors.Blazor;

public class TreeListDataColumnModel : DxGridDataColumnModel
{
    public new RenderFragment<TreeListDataColumnCellDisplayTemplateContext> CellDisplayTemplate
    {
        get => GetPropertyValue<RenderFragment<TreeListDataColumnCellDisplayTemplateContext>>(null, "TreeListCellDisplayTemplate");
        set => SetPropertyValue(value, propertyName: "TreeListCellDisplayTemplate");
    }

    [EditorBrowsable(EditorBrowsableState.Never)]
    public new bool Has_CellDisplayTemplate => HasPropertyValue("TreeListCellDisplayTemplate");

    private static GridDataColumnCellDisplayTemplateContext Convert(TreeListDataColumnCellDisplayTemplateContext context)
    {
        var dataProvider = typeof(GridColumnCellDisplayTemplateContextBase)
            .GetProperty("DataProvider", BindingFlags.NonPublic | BindingFlags.Instance)
            .GetValue(context) as IGridBaseDataProvider;

        var renderHelper = typeof(GridColumnCellDisplayTemplateContextBase)
            .GetProperty("RenderHelper", BindingFlags.NonPublic | BindingFlags.Instance)
            .GetValue(context) as GridRenderHelperBase;

        var constructor = typeof(GridDataColumnCellDisplayTemplateContext).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[0];
        var parameters = new object[] { context.TreeList, dataProvider, renderHelper, null, context.DataColumn as IGridColumn, context.VisibleIndex };

        return (GridDataColumnCellDisplayTemplateContext)constructor.Invoke(parameters);
    }

    public static TreeListDataColumnModel Convert(DxGridDataColumnModel sourceModel)
    {
        var targetModel = new TreeListDataColumnModel();
        var properties = sourceModel.GetType().GetProperties();
        foreach (var property in properties.Where(p => p.Name.StartsWith("Has_")))
        {
            if ((bool)property.GetValue(sourceModel))
            {
                var realPropertyName = property.Name["Has_".Length..];
                var realProperty = properties.First(p => p.Name == realPropertyName);

                if (realPropertyName == nameof(CellDisplayTemplate))
                {
                    var template = (RenderFragment<GridDataColumnCellDisplayTemplateContext>)realProperty.GetValue(sourceModel);
                    targetModel.CellDisplayTemplate = context => builder => template(Convert(context))(builder);
                }
                else
                {
                    realProperty.SetValue(targetModel, realProperty.GetValue(sourceModel));
                }
            }
        }
        return targetModel;
    }

    public override Type ComponentType => typeof(DxTreeListDataColumn);
}
